﻿// Copyright: 2012 
// Author: Minh Vu - YoungJ
// File name: Feed.cs
// Solution: WindowsPhoneRssReader
// Project: WindowsPhoneRssReader
// Time: 12:53 PM 07/05/2012

using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Xml.Linq;
using WindowsPhoneRssReader.Utils;

namespace WindowsPhoneRssReader.Models
{
    public class Feed : MyBase
    {
        public Feed()
        {
            FeedStatus = "Loading...";
            FeedItems = new ObservableCollection<FeedItem>();
        }

        public void LoadFeed()
        {
            if (IsDataLoaded) return;
            if (GetFeedInLocal())
            {
                Debug.WriteLine("read local");
                return;
            }

            GetFeedInWeb();
        }

        private void GetFeed(string xml)
        {
            var rssFeed = XElement.Parse(xml);
            var items = from item in rssFeed.Descendants("item")
                        select new FeedItem
                        {
                            Title = item.GetValue("title"),
                            Description = item.GetDescription(),
                            Url = item.GetValue("link"),
                            DatePublished = item.GetValue("pubDate").ConvertToDateTime(),
                            Read =
                                !string.IsNullOrEmpty(item.GetValue("read")) &&
                                bool.Parse(item.GetValue("read")),
                            Favourite =
                            !string.IsNullOrEmpty(item.GetValue("favourite")) &&
                            bool.Parse(item.GetValue("favourite")),
                            ParentFeed = this
                        };
            foreach (var item in items.OrderByDescending(i=>i.DatePublished).Take(30))
            {
                item.PropertyChanged += (s, e2) => UpdateFeedStatus();

                FeedItems.Add(item);
            }


            ParentModel.UpdateLatestItems();
            UpdateFeedStatus();
        }

        public void GetFeedInWeb()
        {
            var webClient = new WebClient();
            webClient.DownloadStringCompleted += webClient_DownloadStringCompleted;
            webClient.DownloadStringAsync(new Uri(FeedUrl, UriKind.Absolute));
        }

        void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            IsDataLoaded = true;
            try
            {
                if (e.Error != null)
                {
                    Error = e.Error.Message;
                    return;
                }
                var xml = e.Result;
                GetFeed(xml);

                var oldFeedItems = XmlAction.GetFeedItems(Id);
                if (oldFeedItems != null)
                    foreach (var item in FeedItems)
                    {
                        var tmp = item;
                        foreach (var oldItem in oldFeedItems.Where(oldItem => tmp.Url.Equals(oldItem.Url)))
                        {
                            if (!item.Favourite && oldItem.Favourite)
                            {
                                item.Favourite = oldItem.Favourite;
                                Debug.WriteLine("new item is modified");
                            }
                            if (!item.Read && oldItem.Read)
                                item.Read = oldItem.Read;


                        }
                    }

                Debug.WriteLine("save feed:" + XmlAction.SaveFeed(this));
                Debug.WriteLine("Read feed in web");
            }
            catch (Exception exception)
            {
                Debug.WriteLine("Download complete: " + exception.Message);
            }

        }



        private bool GetFeedInLocal()
        {
            IsDataLoaded = true;
            var xml = XmlAction.ReadFeed(Id);
            if (string.IsNullOrEmpty(xml)) return false;
            GetFeed(xml);
            return true;
        }

        private void UpdateFeedStatus()
        {
            if (!FeedItems.Any(item => item.Read || item.Favourite))
            {
                Read = false;
                UnReadItems = FeedItems.Count;
                FeedStatus = string.Format("{0} unread items", UnReadItems);
            }
            else
            {
                var readItems = FeedItems.Count(item => item.Read || item.Favourite);
                UnReadItems = FeedItems.Count - readItems;
                FeedStatus = string.Format("{0} unread, {1} items", UnReadItems, FeedItems.Count);
                Read = readItems == FeedItems.Count;
            }
        }


        //contructor
        private string _feedName;
        public string FeedName
        {
            get { return _feedName; }
            set
            {
                if (string.IsNullOrEmpty(value)) return;
                _feedName = value;
                NotifyPropertyChanged("FeedName");
            }
        }

        private string _feedUrl;
        public string FeedUrl
        {
            get { return _feedUrl; }
            set
            {
                if (string.IsNullOrEmpty(value)) return;
                _feedUrl = value;
                NotifyPropertyChanged("FeedUrl");
            }
        }

        private string _feedStatus;
        public string FeedStatus
        {
            get { return _feedStatus; }
            set
            {
                if (string.IsNullOrEmpty(value)) return;
                _feedStatus = value;
                NotifyPropertyChanged("FeedStatus");
            }
        }

        private int _unReadItems;
        public int UnReadItems
        {
            get { return _unReadItems; }
            set
            {
                _unReadItems = value;
                NotifyPropertyChanged("UnReadItems");
            }
        }

        private bool _read;
        public bool Read
        {
            get { return _read; }
            set
            {
                _read = value;
                NotifyPropertyChanged("Read");
            }
        }

        private RssReader _parentModel;
        public RssReader ParentModel
        {
            get { return _parentModel; }
            set
            {
                if (value == null) return;
                _parentModel = value;
            }
        }


        private FeedItem _currentFeedItem;
        public FeedItem CurrentFeedItem
        {
            get { return _currentFeedItem; }
            set
            {
                if (value == null) return;
                _currentFeedItem = value;
                NotifyPropertyChanged("CurrentFeedItem");
            }
        }


        public ObservableCollection<FeedItem> FeedItems { get; set; }

        private string _error;
        public string Error
        {
            get { return _error; }
            set
            {
                if (string.IsNullOrEmpty(value)) return;
                _error = value;
                NotifyPropertyChanged("Error");
            }
        }
        public bool IsDataLoaded { get; set; }
        public int Id { get; set; }
    }
}